package cn.miao.config;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.miao.hrm.domain.Login;
import cn.miao.hrm.domain.Permission;
import cn.miao.hrm.mapper.LoginMapper;
import cn.miao.hrm.mapper.PermissionMapper;
import cn.miao.hrm.service.ILoginService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 查询具体的用户
 *
 * @author MiaoDaWei
 * @date 2021/12/05
 */
@Component
@Slf4j
public class MyUserDetailService implements UserDetailsService {

    @Autowired
    private ILoginService loginService ;

    @Autowired
    private PermissionMapper permissionMapper ;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        Login login = loginService.selectOne(new EntityWrapper<Login>().eq("username", username));
        Assert.notNull(login, "用户不存在!");

        //查询用户的权限
        List<GrantedAuthority> authorities = new ArrayList<>();
        List<Permission> permissions = permissionMapper.selectPermissionsByUserId(login.getId());
        if(CollUtil.isNotEmpty(permissions)){
            authorities = permissions.stream().map(p -> new SimpleGrantedAuthority(p.getSn()) ).collect(Collectors.toList());
        }

        log.info("加载用户的权限 {}",authorities);
        authorities.forEach(System.out::println);

        //获取用户上下文信息, 那么可以用户登录的时候通过查询的login就查询出所需要的字段信息,放入token中
        //下次获取的时候我们可以通过scurity中的ScurityContextHolder来获取用户的信息

        Map<Object, Object> build = MapUtil.builder().put("id", login.getId()).put("username", login.getUsername()).put("tenantId", login.getTenantId()).put("tenantName", login.getTenantName()).build();
        //用户名
        return new User(JSONObject.toJSONString(build),
                login.getPassword(),//密码
                true,true,true,true,
                authorities);//权限
    }

}
